package org.fireflow2.designer.eclipse.util;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.namespace.QName;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.draw2d.TextUtilities;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.fireflow.pdl.fpdl20.diagram.basic.Label;
import org.firesoa.common.schema.NameSpaces;

public class Util4Eclipse {
	private static final List<QName> BASIC_DATATYPES = new ArrayList<QName>();
	static {
		BASIC_DATATYPES.add(new QName(NameSpaces.JAVA.getUri(),"java.lang.String",NameSpaces.JAVA.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.JAVA.getUri(),"java.util.Date",NameSpaces.JAVA.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.JAVA.getUri(),"int",NameSpaces.JAVA.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.JAVA.getUri(),"boolean",NameSpaces.JAVA.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.JAVA.getUri(),"float",NameSpaces.JAVA.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.JAVA.getUri(),"double",NameSpaces.JAVA.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.JAVA.getUri(),"short",NameSpaces.JAVA.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.JAVA.getUri(),"long",NameSpaces.JAVA.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.JAVA.getUri(),"byte[]",NameSpaces.JAVA.getPrefix()));
		
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"string",NameSpaces.XSD.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"date",NameSpaces.XSD.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"dateTime",NameSpaces.XSD.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"int",NameSpaces.XSD.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"boolean",NameSpaces.XSD.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"float",NameSpaces.XSD.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"double",NameSpaces.XSD.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"short",NameSpaces.XSD.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"long",NameSpaces.XSD.getPrefix()));
		BASIC_DATATYPES.add(new QName(NameSpaces.XSD.getUri(),"base64Binary",NameSpaces.XSD.getPrefix()));
	}
	public static List<QName> getBasicDataTypes(){
		return BASIC_DATATYPES;
	}
	
	
	
	public static Point getAbsolutePosition(Composite control){
		Composite parent = control.getParent();
		if (control.getParent()==null){
			Rectangle rect = control.getBounds();
			return new Point(rect.x,rect.y);
		}else{
			Rectangle thisBounds = control.getBounds();
			Point p = getAbsolutePosition(parent);
			return new Point(thisBounds.x+p.x,thisBounds.y+p.y);
			
		}
		
	}
	
	public static Point getPopupMenuLocation4ToolItem(ToolItem toolItem){
		ToolBar toolBar = toolItem.getParent();

		Rectangle bound = toolItem.getBounds();
		
		Point p = Util4Eclipse.getAbsolutePosition(toolBar);
		return new Point(p.x+bound.x+5,p.y+bound.y+72);
	}
	
	public static Dimension getTextSize(Label fireLabel,String displayName){
		String s = fireLabel.getText();
		if (Label.CONTENT_FROM_WORKFLOW_ELEMENT.equals(fireLabel.getText())){
			s = displayName;
		}
		if (s==null || s.trim().equals("")){
			return new Dimension(-1,-1);
		}
		Font font = getFont(fireLabel);
		return TextUtilities.INSTANCE.getTextExtents(s, font);
	}
	
	public static Font getFont(Label fireLabel){
	    String fontName = "Trebuchet MS";
	    Font systemFont = Display.getCurrent().getSystemFont();
	    if (fireLabel==null || fireLabel.getFont()==null){
	    	return systemFont;
	    }
	    if (systemFont!=null && systemFont.getFontData().length>0){
	    	FontData fd = systemFont.getFontData()[0];
	    	if (fd.getName()!=null){
	    		fontName = fd.getName();
	    	}		    	
	    }
	    int fontStyle = SWT.NORMAL;
	    if (org.fireflow.pdl.fpdl20.diagram.style.Font.FONT_WEIGHT_BOLD.equals(fireLabel.getFont().getWeight())){
	    	fontStyle = SWT.BOLD;
	    }
	    int size = 10;
	    if (fireLabel.getFont().getSize()>0){
	    	size = fireLabel.getFont().getSize();
	    }
	    Font newFont = new Font(Display.getCurrent(),fontName,size,fontStyle);
	    return newFont;
	}

	public static Color colorStr2ColorObj(String colorStr){
		if (colorStr==null )return null;
		if (colorStr.startsWith("#")){
			if (colorStr.length()!=7){
				return null;//格式不正确
			}else{
				colorStr = colorStr.substring(1);
			}
		}else if (colorStr.length()!=6){
			return null;//格式不正确
		}
		try{
			int r = Integer.parseInt(colorStr.substring(0, 2),16);
			int b = Integer.parseInt(colorStr.substring(2,4),16);
			int g = Integer.parseInt(colorStr.substring(4,6),16);
			
			Color c = new Color(Display.getCurrent(),r,b,g);
			return c;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
	
    /** 
     *   对单独的className进行校验 
     * @param className 
     * @return 
     */  
    public static   boolean isValidJavaIdentifier(String className) {  
        //确定是否允许将指定字符作为 Java 标识符中的首字符。  
        if (className.length() == 0  
                || !Character.isJavaIdentifierStart(className.charAt(0)))  
            return false;  
  
        String name = className.substring(1);  
        for (int i = 0; i < name.length(); i++)  
            //确定指定字符是否可以是 Java 标识符中首字符以外的部分。  
            if (!Character.isJavaIdentifierPart(name.charAt(i)))  
                return false;  
  
        return true;  
    }  
    /** 
     *  对 package name 和 class name 进行校验 
     * @param fullName 
     * @return 
     */  
    public static boolean isValidJavaFullClassName(String fullName){  
        if(fullName.equals("")){  
            return false;  
        }  
        boolean flag = true;  
        try{  
            if(!fullName.endsWith(".")){  
                int index = fullName.indexOf(".");  
                if(index!=-1){  
                    String[] str = fullName.split("\\.");  
                    for(String name : str){  
                        if(name.equals("")){  
                            flag = false;  
                            break;  
                        }else if(!isValidJavaIdentifier(name)){  
                            flag = false;  
                            break;  
                        }  
                    }  
                }else if(!isValidJavaIdentifier(fullName)){  
                    flag = false;  
                }  
  
            }else {  
                flag = false;  
            }  
              
        }catch(Exception ex){  
            flag = false;  
            ex.printStackTrace();  
        }  
        return flag;  
    }  
    
    public static String errorStackToString(Exception exception) {
//    	SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ");
        ByteArrayOutputStream byteStream;
        try {
            byteStream = new ByteArrayOutputStream(4096);
            PrintWriter printStream = new PrintWriter(byteStream);
            exception.printStackTrace(printStream);
            printStream.flush();
            return byteStream.toString();
        } catch (Exception ex) {
            return exception.toString();
        }
    }
    
    /**
     * 找到一个类的所有public方法，
     * @param iType
     * @return
     */
    public static List<IMethod> findAllPublicMethodsFromIType(IType iType){
    	final List<IMethod> allMethods = new ArrayList<IMethod>();
		IJavaSearchScope scope = null;
		try {
			scope = SearchEngine.createHierarchyScope(iType);

			SearchPattern pattern = SearchPattern.createPattern("*",
					IJavaSearchConstants.METHOD,
					IJavaSearchConstants.DECLARATIONS,
					SearchPattern.R_PATTERN_MATCH);
			SearchRequestor requestor = new SearchRequestor() {

				@Override
				public void acceptSearchMatch(SearchMatch match)
						throws CoreException {
					Object method = match.getElement();
					if (method instanceof IMethod){
						allMethods.add((IMethod)method);
					}
				}

			};
			new SearchEngine().search(pattern,
					new SearchParticipant[] { SearchEngine
							.getDefaultSearchParticipant() }, scope,
					requestor, null);
		} catch (JavaModelException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Object obj = iType.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
		//过滤
		Iterator<IMethod> iterator = allMethods.iterator();
		while(iterator.hasNext()){
			IMethod m = iterator.next();
			try {
				if (m.isConstructor() || m.isMainMethod()
						||(m.getFlags() & Flags.AccPublic)==0){
					iterator.remove();
				}
			} catch (JavaModelException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
    	return allMethods;
    }
    
    public static String signatureToFullTypeName(String signature){
    	String packageName = Signature.getSignatureQualifier(signature);
    	String fullName = (packageName.trim().equals("")?"":packageName+".") +
    	Signature.getSignatureSimpleName(signature);
    	return fullName;
    }
    
    public static String signatureToSimpleTypeName(String signature){
    	return Signature.getSignatureSimpleName(signature);
    }
    
    /**
     * 将IMethod对象转换成String表达
     * @param method
     * @return
     */
	public static String methodToString(IMethod method){
		StringBuffer sbuf = new StringBuffer();
		sbuf.append(method.getElementName());
		sbuf.append("(");
		try {
			String[] paramNames = method.getParameterNames();
			String[] paramTypes = method.getParameterTypes();
			if (paramNames!=null && paramNames.length>0){
				for (int i=0;i<paramNames.length;i++){
					sbuf.append(Util4Eclipse.signatureToSimpleTypeName(paramTypes[i])).append(" ");
					sbuf.append(paramNames[i]);
					if (i<(paramNames.length-1)){
						sbuf.append(",");
					}
				}
			}
		} catch (JavaModelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		sbuf.append(")");
		
		
		try {
			String returnType = method.getReturnType();
			
			sbuf.append(" : ").append(Util4Eclipse.signatureToSimpleTypeName(returnType));
		} catch (JavaModelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sbuf.toString();
	}
	
	public static boolean strEquals(String s1,String s2){
		String temp1 = s1==null?"":s1;
		String temp2 = s2==null?"":s2;
		if (temp1.trim().equals(temp2.trim())){
			return true;
		}else{
			return false;
		}
	}
}
